package com.jd.cs.config.interceptor;

import com.jd.cs.anotation.CheckToken;
import com.jd.cs.common.Const;
import com.jd.cs.config.JwtConfig;
import com.jd.cs.error.ErrorCode;
import com.jd.cs.exception.APIException;
import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.SignatureException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Date;

@Component
public class JWTTokenInterceptor extends HandlerInterceptorAdapter {

    @Resource
    private JwtConfig jwtConfig;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws SignatureException {
        // 如果不是映射到方法直接通过
        if (!(object instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) object;
        Method method = handlerMethod.getMethod();
        //检查有没有需要用户权限的注解
        if (method.isAnnotationPresent(CheckToken.class)) {
            CheckToken userLoginToken = method.getAnnotation(CheckToken.class);
            if (userLoginToken.required()) {
                String token = request.getHeader(Const.Header.TOKEN);
                if (StringUtils.isEmpty(token)) {
                    throw new APIException(ErrorCode.E_20000);
                }
                Jwt jwt = jwtConfig.parse(token);
                if (jwt == null) {
                    throw new SignatureException(ErrorCode.E_20001.getMsg());
                }
                Date expirationDateFromToken = jwtConfig.getExpirationDateFromToken(token);
                boolean tokenExpired = jwtConfig.isTokenExpired(expirationDateFromToken);
                if (tokenExpired) {
                    throw new SignatureException("token Expired");
                }
                return true;
            }
        }
        return true;
    }
}